package com.zjy.business.system.manager.service.impl;

import com.zjy.business.system.common.SysPermissionCommon;
import com.zjy.business.system.dao.SysMenuDao;
import com.zjy.business.system.dao.SysRoleMenuDao;
import com.zjy.business.system.domain.entity.SysMenu;
import com.zjy.business.system.domain.manager.form.ManagerSysMenuSaveOrUpdateForm;
import com.zjy.business.system.domain.manager.vo.ManagerSysMenuListVo;
import com.zjy.business.system.manager.service.ManagerSysMenuService;
import com.zjy.common.constant.EntityConstant;
import com.zjy.common.constant.StringConstant;
import com.zjy.common.utils.ConvertBeanUtils;
import com.zjy.web.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author yxb
 * create_time: 2024-10-22 16:55
 * description: 
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ManagerSysMenuServiceImpl implements ManagerSysMenuService {

    final private SysMenuDao sysMenuDao;

    final private SysRoleMenuDao sysRoleMenuDao;

    final private SysPermissionCommon sysPermissionCommon;


    @Override
    @Transactional
    public void saveOrUpdate(ManagerSysMenuSaveOrUpdateForm form) {
        // 校验参数
        checkSaveOrUpdateForm(form);
        if (Objects.isNull(form.getId())) {
            SysMenu convert = ConvertBeanUtils.convert(form, SysMenu.class);
            sysMenuDao.save(convert);
        } else {
            SysMenu sysMenu = sysMenuDao.getById(form.getId());
            if (Objects.isNull(sysMenu)) {
                throw BusinessException.EXCEPTION("菜单不存在");
            }
            sysMenu.setMenuName(form.getMenuName());
            sysMenu.setParentId(form.getParentId());
            sysMenu.setOrderNum(form.getOrderNum());
            sysMenu.setPath(form.getPath());
            sysMenu.setComponent(form.getComponent());
            sysMenu.setQueryParam(form.getQueryParam());
            sysMenu.setIsFrame(form.getIsFrame());
            sysMenu.setIsCache(form.getIsCache());
            sysMenu.setMenuType(form.getMenuType());
            sysMenu.setVisible(form.getVisible());
            sysMenu.setStatus(form.getStatus());
            sysMenu.setPerms(form.getPerms());
            sysMenu.setIcon(form.getIcon());
            sysMenu.setRemark(form.getRemark());
            sysMenuDao.updateByIdUpdateCache(sysMenu, SysMenu::getId, form.getId());
            sysPermissionCommon.clearByMenuId(form.getId());
        }
    }


    /**
     * 校验参数
     * @param form 请求体
     */
    private void checkSaveOrUpdateForm(ManagerSysMenuSaveOrUpdateForm form) {
        Long parentId = form.getParentId();
        Long id = form.getId();
        if (Objects.nonNull(parentId) && !Objects.equals(parentId, StringConstant.MENU_TOP_PARENT_ID)) {
            if (Objects.nonNull(id)) {
                if (Objects.equals(form.getParentId(), id)) {
                    throw BusinessException.EXCEPTION("父级菜单不能是当前菜单");
                }
            }
            if (Objects.isNull(sysMenuDao.findCacheOne(SysMenu::getId, parentId))) {
                throw BusinessException.EXCEPTION("父级菜单不存在");
            }
        }
        if (StringUtils.isNotBlank(form.getPerms())) {
            sysMenuDao.lambdaQuery()
                    .select(SysMenu::getId)
                    .eq(SysMenu::getPerms, form.getPerms())
                    .eq(Objects.nonNull(parentId), SysMenu::getParentId, parentId)
                    .ne(Objects.nonNull(id), SysMenu::getId, id)
                    .oneOpt().ifPresent(sysMenu -> {
                        throw BusinessException.EXCEPTION("已存在相同权限标识");
                    });
        }
    }

    @Override
    @Transactional
    public void remove(Long id) {
        SysMenu sysMenu = sysMenuDao.getById(id);
        if (Objects.isNull(sysMenu)) {
            throw BusinessException.EXCEPTION("数据不存在");
        }
        if (sysMenuDao.lambdaQuery().eq(SysMenu::getParentId, id)
                .count() > 0) {
            throw BusinessException.EXCEPTION("存在子数据,请先删除子数据");
        }
        long count = sysRoleMenuDao.checkMenuIsBindRole(id);
        if (count > 0) {
            throw BusinessException.EXCEPTION("菜单项已设置角色,不能删除");
        }
        sysMenuDao.removeByIdDeleteCache(id, SysMenu::getId, id);
    }

    @Override
    public List<ManagerSysMenuListVo> getSysMenu() {
        List<SysMenu> sysMenuList = sysMenuDao.list();
        if (sysMenuList.isEmpty()) {
            return List.of();
        }
        Map<Long, List<ManagerSysMenuListVo>> menuMap = new HashMap<>();
        for (SysMenu item : sysMenuList) {
            List<ManagerSysMenuListVo> list = menuMap.getOrDefault(item.getParentId(), new ArrayList<>());
            list.add(ConvertBeanUtils.convert(item, ManagerSysMenuListVo.class));
            menuMap.put(item.getParentId(), list);
        }
        return sysMenuDao.getSysMenuList(EntityConstant.FATHER_ID, menuMap);
    }

}
